<?php
/*
 * @Descripttion:重型设备检查表管理
 * @version: v1
 */

declare(strict_types=1);

namespace app\certificate\controller\admin\v1\checklist;

use DateTime;
use Exception;
use libs\ALiOss;
use Spipu\Html2Pdf\Exception\Html2PdfException;
use think\Request;
use think\facade\Db;

class Index
{

  /**
   * @Description: 查看列表
   */
  public function getList(Request $request)
  {
    $data = $request->data;
    $searchWhere = [
      ['rt.projectCode', '=', $request->prjCode],
    ];
    $status = $data['status'];
    // 获取当前日期
    $currentDate = date('Y-m-d'); // 当前时间
    //状态,使用中-1,已审批-2, 过期未审批-3
    if ($status == '1') { // 使用中
      $searchWhere[] = ['r.weekStartDate', '<=', $currentDate];
      $searchWhere[] = ['r.weekEndDate', '>=', $currentDate];
      $searchWhere[] = ['r.status', '=', 1];
    } elseif ($status == '2') { // 已审批
      $searchWhere[] = ['r.status', '=', 2];
    } elseif ($status == '3') { // 过期未审批
      $searchWhere[] = ['r.weekEndDate', '<', $currentDate];
      $searchWhere[] = ['r.status', '=', 1];
    }

    if (!empty($data['workerName'])) array_push($searchWhere, ['wi.name', 'like', "%{$data['workerName']}%"]);
    if (!empty($data['typeUuid'])) array_push($searchWhere, ['r.typeUuid', '=', $data['typeUuid']]);
    if (isset($request->authWhere['corpCode'])) array_push($searchWhere, ['rt.corpCode', '=', $request->authWhere['corpCode']]);
    if (!empty($data['machineUuid'])) array_push($searchWhere, ['r.machineUuid', '=', $data['machineUuid']]);

    $list = DB::table('certificate_heavyMachineCheck')
      ->alias('r')
      ->join('certification_projectWorker wi', 'wi.wxappUserUuid = r.wxappUserUuid', 'left')
      ->join('certificate_heavyMachineCheckType rt', 'rt.uuid = r.typeUuid')
      ->join('certificate_area a', 'a.uuid = r.areaUuid', 'left')
      ->join('certification_projectWorker wa', 'wa.wxappUserUuid = r.auditUserUuid', 'left')
      ->join('certification_projectWorker ww', 'ww.wxappUserUuid = r.manageUserUuid', 'left')
      ->where($searchWhere)
      ->page((int)$data['page'], (int)$data['limit'])
      ->field(['r.serialNumber', 'r.title', 'r.machineSn', 'rt.name as typeName', 'r.inDate', 'r.status', 'r.uuid', 'r.reason', 'wi.workerName as dayUserName', 'ww.workerName as weekUserName', 'wa.workerName as auditUserName', 'r.auditTime', 'r.weekEndDate'])
      ->order('r.id desc')
      ->distinct(true)
      ->select()->toArray();
    foreach ($list as &$item) {
      $item['dayCheckedNums'] =  DB::table('certificate_heavyMachineCheckRecord')->where('checkUuid', $item['uuid'])->where('isDelete', 0)->where('type', 1)->count();
      $item['weekCheckedNums'] =  DB::table('certificate_heavyMachineCheckRecord')->where('checkUuid', $item['uuid'])->where('isDelete', 0)->where('type', 2)->count();
      $item['todayCheckedNums'] =  DB::table('certificate_heavyMachineCheckRecord')->where('checkUuid', $item['uuid'])->where('isDelete', 0)->where('type', 1)->where('checkDate', date('Y-m-d'))->count();
      //状态,使用中-1,已审批-2, 过期未审批-3
      if ($item['status'] == 1 && strtotime($item['weekEndDate']) < strtotime($currentDate)) {
        $item['status'] = 3;
      }
    }

    $count =  DB::table('certificate_heavyMachineCheck')
      ->alias('r')
      ->join('certification_workerInfo wi', 'wi.wxappUserUuid = r.wxappUserUuid')
      ->join('certificate_heavyMachineCheckType rt', 'rt.uuid = r.typeUuid')
      ->join('certificate_area a', 'a.uuid = r.areaUuid', 'left')
      ->where($searchWhere)
      ->distinct(true)
      ->count();

    $data  =  compact('list', 'count');
    return result(SUCCESS, $data, '');
  }
  /**
   * @Description: 
   */
  public function getDetail(Request $request)
  {

    $data = $request->data;
    $uuid = $data['uuid'];
    $data = DB::table('certificate_heavyMachineCheck')
      ->alias('r')
      ->join('certificate_heavyMachineCheckType rt', 'rt.uuid = r.typeUuid')
      ->join('certificate_area a', 'a.uuid = r.areaUuid', 'left')
      ->where('r.uuid', $uuid)
      ->field(['r.serialNumber', 'r.title', "rt.subtitle", 'r.machineSn', 'rt.name', "r.owner", 'weekStartDate', 'weekEndDate', 'r.typeUuid', "rt.dayFormUuid", "rt.weekFormUuid", "rt.auditFormUuid"])
      ->find();
    if (!$data) return result(FAIL, [], '数据有误请重试');
    $data['noSubtitle'] = str_replace("Inspection of ", "", $data["subtitle"]) . ' No.';
    $data['noName'] = str_replace("檢查記錄", "", $data["name"]) . ' 編號';

    $templates = DB::table('certificate_formtemplate')->where('uuid', 'in', [$data['dayFormUuid'], $data['weekFormUuid'], $data['auditFormUuid']])->field(['fields', 'type'])->select();
    foreach ($templates as $item) {
      $template[$item['type']] = $item['fields'];
    }
    $weekFormData = $this->formatData($this->getFormData($uuid, 2) ?? $template['checklistWeek']);
    $spliced =  array_splice($weekFormData, -3);
    $weekFormData = [$weekFormData, $spliced];
    $data['weekFormData']  = $weekFormData;
    $data['auditFormData'] = $this->formatData($this->getFormData($uuid, 3) ?? $template['checklistAudit']);
    $weekStartDate = $data['weekStartDate'];
    $weekEndDate = $data['weekEndDate'];
    unset($data['weekStartDate'], $data['weekEndDate'], $data['dayFormUuid'], $data['weekFormUuid'], $data['auditFormUuid']);

    // 转换为 DateTime 对象
    $startDate = new DateTime($weekStartDate);
    $endDate = new DateTime($weekEndDate);
    // 创建一个空数组来存储结果
    $datesWithWeekdays = [];
    // 使用 DateInterval 来遍历每一天
    // 星期几的英文到中文的映射
    $weekdays = [
      'Monday'    => '星期一',
      'Tuesday'   => '星期二',
      'Wednesday' => '星期三',
      'Thursday'  => '星期四',
      'Friday'    => '星期五',
      'Saturday'  => '星期六',
      'Sunday'    => '星期天'
    ];

    $dayTemplate = $this->formatData($template['checklistDay']);
    while ($startDate <= $endDate) {
      // 获取当前日期的星期几
      $weekday = $startDate->format('l');  // 'l' 返回完整的星期几名称（如：Monday, Tuesday）
      //当前日期是否申请
      $dayRecord = $this->getFormData($uuid, 1, ['checkDate' => $startDate->format('Y-m-d')]);
      $formData = $this->formatData($dayRecord ?? "{}");
      $isSubmited =  $dayRecord ? 1 : 0;
      // 将日期和星期几存入数组
      $datesWithWeekdays[] = [
        'date'       => $startDate->format('Y-m-d'),   //格式化日期为 'YYYY-MM-DD'
        'weekday'    => $weekday,                      //星期几
        'isSubmited' => $isSubmited,                   //是否提交,是-1，否-0
        'weekdayText' => $weekdays[$weekday],
        'formData' => $formData,
      ];
      // 移动到下一天
      $startDate->modify('+1 day');
      $dayTemplate = array_merge($formData, $dayTemplate);
    }
    $data['weekdays'] = $datesWithWeekdays;
    // 用于保存去重后的数组
    $dayFormData = [];
    // 用于记录已存在的label
    $seenLabels = [];

    foreach ($dayTemplate as $item) {
      if (!in_array($item['label'], $seenLabels)) {
        // 如果label没有被记录过，则将其加入结果数组和已见数组
        $dayFormData[] = $item;
        $seenLabels[] = $item['label'];
      }
    }
    $data['dayFormData'] = $dayFormData;
    return result(SUCCESS, $data, '');
  }

  function getFormData($uuid, $type, $other = [])
  {
    $where = [
      'checkUuid' => $uuid,
      'type' => $type
    ];
    $where = array_merge($where, $other);
    return  DB::table('certificate_heavyMachineCheckRecord')
      ->where($where)
      ->value('formData');
  }

  public function formatData($formData)
  {

    $formData =  json_decode(html_entity_decode($formData), true);
    $data = [];
    foreach ($formData as $key => $value) {
      $data[] = [
        'label' => isset($value['label']) ? $value['label'] : '',
        'defaultValue' => $value['defaultValue'] ?? '',
        'renderKey' => $value['renderKey'],
        'subtitle' => isset($value['subtitle']) ? $value['subtitle'] : '',
        'tag' => $value['tag'],
      ];
    }
    return $data;
  }

  public function formatFormData1($formData, $subFormData)
  {
    $templateData =  json_decode(html_entity_decode($formData), true);
    // 使用 array_map 提取 id 和 name 字段
    $templateData = array_map(function ($item) {
      return [
        'tag' => isset($item['tag']) ? $item['tag'] : null,
        'label' => isset($item['label']) ? $item['label'] : null,
        'defaultValue' => isset($item['defaultValue']) ? $item['defaultValue'] : null,
        'renderKey' => isset($item['renderKey']) ? $item['renderKey'] : null,
        'subtitle' => isset($item['subtitle']) ? $item['subtitle'] : null,
      ];
    }, $templateData);
    $templateData = array_column($templateData, null, 'renderKey');

    foreach ($subFormData as $key => $value) {
      $value['formData'] = json_decode(html_entity_decode($value['formData'] ?? ''), true) ?: [];
      foreach ($value['formData'] as $key1 => $value1) {
        if (isset($templateData[$value1['renderKey']])) {
          $templateData[$value1['renderKey']]['defaultValue'] = isset($value1['defaultValue']) ? $value1['defaultValue'] : null;
        } else {
          $templateData[$value1['renderKey']] = [
            'label' => isset($value1['label']) ? $value1['label'] : null,
            'defaultValue' => isset($value1['defaultValue']) ? $value1['defaultValue'] : null,
            'renderKey' => isset($value1['renderKey']) ? $value1['renderKey'] : null,
            'subtitle' => isset($value1['subtitle']) ? $value1['subtitle'] : null,
            'tag' => isset($value1['tag']) ? $value1['tag'] : null,
          ];
        }
      }
    }
    $templateData = array_values($templateData);
    return $templateData;
  }

  /**
   * html转pdf
   *
   * @param Request $request
   * @return void
   */
  public function html2Pdf(Request $request)
  {
    $data     = $request->data;
    $uuid     = $data['uuid']; //许可证唯一码
    try {

      $info = DB::table('certificate_heavyMachineCheck')
        ->alias('r')
        ->join('certificate_heavyMachineCheckType rt', 'rt.uuid = r.typeUuid')
        ->join('certificate_area a', 'a.uuid = r.areaUuid', 'left')
        ->where('r.uuid', $uuid)
        ->find();
      if (!$info) return result(FAIL, [], '数据有误请重试');
      if($info['status'] != 2) return result(FAIL, [], '检查表未审批通过');

      $exec = exec('whereis wkhtmltopdf', $oupput, $result_code);
      if (!$exec) {
        return result(FAIL, '', 'wkhtmltopdf工具未安装,请联系管理员');
      }
      $domain = request()->domain();
      $url = $domain . "/api/certificate/admin/v1/checklist/index/pdf?uuid={$uuid}";

      $path2 = 'uploads/' . time() . '.pdf';
      $path = root_path() . '/public/' . $path2;
      // 获取文件的目录路径
      $dir = dirname($path);
      // 判断目录是否存在
      if (!is_dir($dir)) {
        // 如果目录不存在，则创建目录
        if (!mkdir($dir, 0777, true)) {
          // 如果创建失败，可以抛出错误或处理异常
          return result(FAIL, '', '创建目录失败');
        }
      }
      $token = $_SERVER["HTTP_AUTHORIZATION"];
      $userUuid = $_SERVER["HTTP_UUID"];
      // 执行 wkhtmltopdf 命令
      $command = "wkhtmltopdf " .
        "--custom-header 'Authorization' {$token} " .
        "--custom-header 'uuid' {$userUuid} " .
        "--custom-header 'corpCode' {$request->corpCode} " .
        "--custom-header 'puuid' {$request->prjCode} " .
        "{$url} {$path}";
      exec($command . ' 2>&1', $output, $result_code);
      // if ($result_code !== 0) {
      //   return result(FAIL, '', implode(',', $output));
      // }
      if (file_exists($path) == false) {
        return result(FAIL, '', '导出pdf失败');
      }
      $exp = explode('.', $path2);
      $oss = new ALiOss($exp[0], $exp[1]);
      $ossPath = $oss->upload($path2);
      @unlink($path);
      return result(SUCCESS, ['path' => $ossPath], '导出路径');
    } catch (Exception $e) {
      return result(FAIL, '', $e->getMessage()());
    }
  }

  public function pdf(Request $request)
  {
    $data = $request->data;
    $uuid = $data['uuid'];
    $data = DB::table('certificate_heavyMachineCheck')
      ->alias('r')
      ->join('certificate_heavyMachineCheckType rt', 'rt.uuid = r.typeUuid')
      ->join('certificate_area a', 'a.uuid = r.areaUuid', 'left')
      ->where('r.uuid', $uuid)
      ->field(['r.serialNumber', 'r.title', "rt.subtitle", 'r.machineSn', 'rt.name', "r.owner", 'weekStartDate', 'weekEndDate', 'r.typeUuid', "rt.dayFormUuid", "rt.weekFormUuid", "rt.auditFormUuid"])
      ->find();
    if (!$data) return result(FAIL, [], '数据有误请重试');
    $data['noSubtitle'] = str_replace("Inspection of ", "", $data["subtitle"]) . ' No.';
    $data['noName'] = str_replace("檢查記錄", "", $data["name"]) . ' 編號';

    $templates = DB::table('certificate_formtemplate')->where('uuid', 'in', [$data['dayFormUuid'], $data['weekFormUuid'], $data['auditFormUuid']])->field(['fields', 'type'])->select();
    foreach ($templates as $item) {
      $template[$item['type']] = $item['fields'];
    }

    $weekFormData = $this->formatData($this->getFormData($uuid, 2) ?? $template['checklistWeek']);
    $spliced =  array_splice($weekFormData, -3);
    $weekFormData = [$weekFormData, $spliced];
    $data['weekFormData']  = $weekFormData;
    $data['auditFormData'] = $this->formatData($this->getFormData($uuid, 3) ?? $template['checklistAudit']);
    $weekStartDate = $data['weekStartDate'];
    $weekEndDate = $data['weekEndDate'];
    unset($data['weekStartDate'], $data['weekEndDate'], $data['dayFormUuid'], $data['weekFormUuid'], $data['auditFormUuid']);

    // 转换为 DateTime 对象
    $startDate = new DateTime($weekStartDate);
    $endDate = new DateTime($weekEndDate);
    // 创建一个空数组来存储结果
    $datesWithWeekdays = [];
    // 使用 DateInterval 来遍历每一天
    // 星期几的英文到中文的映射
    $weekdays = [
      'Monday'    => '星期一',
      'Tuesday'   => '星期二',
      'Wednesday' => '星期三',
      'Thursday'  => '星期四',
      'Friday'    => '星期五',
      'Saturday'  => '星期六',
      'Sunday'    => '星期天'
    ];

    $dayTemplate = $this->formatData($template['checklistDay']);
    while ($startDate <= $endDate) {
      // 获取当前日期的星期几
      $weekday = $startDate->format('l');  // 'l' 返回完整的星期几名称（如：Monday, Tuesday）
      //当前日期是否申请
      $dayRecord = $this->getFormData($uuid, 1, ['checkDate' => $startDate->format('Y-m-d')]);
      $formData = $this->formatData($dayRecord ?? "{}");
      $isSubmited =  $dayRecord ? 1 : 0;
      // 将日期和星期几存入数组
      $datesWithWeekdays[] = [
        'date'       => $startDate->format('Y-m-d'),   //格式化日期为 'YYYY-MM-DD'
        'weekday'    => $weekday,                      //星期几
        'isSubmited' => $isSubmited,                   //是否提交,是-1，否-0
        'weekdayText' => $weekdays[$weekday],
        'formData' => $formData,
      ];
      // 移动到下一天
      $startDate->modify('+1 day');
      $dayTemplate = array_merge($formData, $dayTemplate);
    }
    $data['weekdays'] = $datesWithWeekdays;

    // 用于保存去重后的数组
    $dayFormData = [];
    // 用于记录已存在的label
    $seenLabels = [];

    foreach ($dayTemplate as $item) {
      if (!in_array($item['label'], $seenLabels)) {
        // 如果label没有被记录过，则将其加入结果数组和已见数组
        $dayFormData[] = $item;
        $seenLabels[] = $item['label'];
      }
    }
    $data['dayFormData'] = $dayFormData;

    return view('', ['data' => $data]);
  }
}
